package com.danco.training.zaneuskaya.controller;



import java.io.IOException;
import java.io.Serializable;
import java.util.Date;


import java.util.List;

import com.danco.training.zaneuskaya.api.BookController;


import com.danco.training.zaneuskaya.communication.MessageAnalyzer;
import com.danco.training.zaneuskaya.domain.Book;
import com.danco.training.zaneuskaya.view.IOUtil;

public class BookControllerImpl implements Serializable, BookController {

	
	private static final String READ_BOOK_LIST_FROM_FILE_MESSAGE = "Enter file to read book list";

	private static final String SAVED_BY_DEFAULT_IN = "Saved by default in ";

	private static final String FILE_TO_SAVE_DESTINATION = "d:\\file3.csv";

	private static final String SAVE_BOOK_LIST_TO_FILE_MESSAGE = "Enter directory and file name :";

	private static final String DELETE_BOOK_MESSAGE = "Enter book Id to delete:";

	private static final String ENTER_NEW_RECEIPT_DATE = "Enter new receipt date yyyy-[m]m-[d]d:";

	private static final String ENTER_NEW_QUANTITY = "Enter new quantity:";

	private static final String ENTER_NEW_PRICE = "Enter new price:";

	private static final String ENTER_NEW_PUBLICATION_DATE = "Enter new publication date yyyy.[m]m.[d]d:";

	private static final String ENTER_NEW_AUTHOR = "Enter new author:";

	private static final String ENTER_NEW_TITLE = "Enter new title:";

	private static final String UPDATE_BOOK_MESSAGE = "Enter book Id to modify: ";

	private static final String BOOK_NOT_EXISTED = "Book not existed";

	private static final String PRINT_BOOK_INFO_MESSAGE = "Enter book's to show Id";

	private static final String ENTER_PUBLICATION_DATE = "Enter publication date yyyy.[m]m.[d]d";

	private static final String ENTER_BOOK_AUTHOR = "Enter book author:";

	private static final String ENTER_BOOK_TITLE_FOR_CREATION = "Enter book title for creation:";

	private static final String PRINT_UNSOLD_BOOKS_SORTED_BY_PRICE = "Unsold Books in Bookstorage  sorted by price";

	private static final String PRINT_UNSOLD_BOOKS_SORTED_BY_RECEIPT_DATE_MESSAGE = "Books in Bookstorage unsold for some months sorted by receipt date";

	private static final String PRINT_NOT_AVAILABLE_BOOKS_MESSAGE = "Not available Books in Bookstorage ";

	private static final String PRINT_AVAILABLE_BOOKS_MESSAGE = "Available Books in Bookstorage ";

	private static final String PRINT_BOOK_LIST_SORTED_BY_PRICE_MESSAGE = "Books in Bookstorage sorted by price";

	private static final String PRINT_BOOK_LIST_SORTED_BY_PUBLICATION_DATE_MESSAGE = "Books in Bookstorage sorted by publication date";

	private static final String PRINT_BOOK_LIST_SORTED_BY_ALPHABET_MESSAGE = "Books in Bookstorage sorted by alphabet";

	private static final String PRINT_BOOK_LIST_MESSAGE = "Books in Bookstorage";

	/**
	 * 
	 */
	private static final long serialVersionUID = 7899256677468012304L;
	
	
	
	

	@SuppressWarnings("unchecked")
	public synchronized void printBookList()  {
		IOUtil.write(PRINT_BOOK_LIST_MESSAGE);
		
		List<Book> books ;
		
			try {
				books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getList", null);
				for (Book book: books){
					IOUtil.write(bookInfo(book.getId()));
				}
			} catch (IOException e) {
				IOUtil.write(e.getMessage());
			} catch (ClassNotFoundException e) {
				IOUtil.write(e.getMessage());
			}
		
		
		
		

	}

	public void printBookListSortedByAlphabet() {
		IOUtil.write(PRINT_BOOK_LIST_SORTED_BY_ALPHABET_MESSAGE);
		List<Book> books;
		List<Book> sortedBooks;
			try {
				books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getList", null);
				sortedBooks = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;sortBooksByAlphabet", new Object []{books});
				for (Book book: sortedBooks){
					IOUtil.write(bookInfo(book.getId()));
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	
		
	}

	public void printBookListSortedByPublicationDate() {
		IOUtil.write(PRINT_BOOK_LIST_SORTED_BY_PUBLICATION_DATE_MESSAGE);
		List<Book> books ;
		
		List<Book> sortedBooks;
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getList", null); 
		sortedBooks = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;sortBooksByPublicationDate",new Object []{ books});
		for (Book book: sortedBooks){
			IOUtil.write(bookInfo(book.getId()));
		}
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	
	
}

	public void printBookListSortedByPrice() {
		IOUtil.write(PRINT_BOOK_LIST_SORTED_BY_PRICE_MESSAGE);
List<Book> books;
List<Book> sortedBooks;
		
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getList", null);
			sortedBooks = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;sortBooksByPrice", new Object []{books});
			for (Book book: sortedBooks){
				IOUtil.write(bookInfo(book.getId()));
			}
		
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	
	
}

	public void printAvailableBooks(){
		IOUtil.write(PRINT_AVAILABLE_BOOKS_MESSAGE);
		List<Book> books;
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getAvailableBooks", null);
			for (Book book: books){
				IOUtil.write(bookInfo(book.getId()));
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
}

	public void printNotAvailableBooks() {
		IOUtil.write(PRINT_NOT_AVAILABLE_BOOKS_MESSAGE);
		List<Book> books;
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getNotAvailableBooks", null);
			for (Book book: books){
				IOUtil.write(bookInfo(book.getId()));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

	public void printUnsoldBooksSortedByReceiptDate() {
		IOUtil.write(PRINT_UNSOLD_BOOKS_SORTED_BY_RECEIPT_DATE_MESSAGE);
List<Book> books ;
List<Book> sortedBooks ;		
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getList", null);
		
		sortedBooks = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;sortUnsoldBooksByReceiptDate", new Object []{books});
		for (Book book: sortedBooks){
			IOUtil.write(bookInfo(book.getId()));
		}
			
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	

	}

	public void printUnsoldBooksSortedByPrice() {
		IOUtil.write(PRINT_UNSOLD_BOOKS_SORTED_BY_PRICE);
List<Book> books;
		
		List<Book> sortedBooks;
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getList", null);
		
		sortedBooks = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;sortUnsoldBooksByPrice", new Object []{books});
		for (Book book: sortedBooks){
			IOUtil.write(bookInfo(book.getId()));
		}
			
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
		

	}

	public void createBook() {
		
		IOUtil.write(ENTER_BOOK_TITLE_FOR_CREATION);
		String title = 
				IOUtil.read();
		IOUtil.write(ENTER_BOOK_AUTHOR);
		String author = IOUtil.read();
		IOUtil.write(ENTER_PUBLICATION_DATE);
		Date date = IOUtil.readDate();
		
		try {
			int id = (int) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;generateUnexistedId", null);
		
		    Book book = new Book(id,title,author,date);
		
		    MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;addEntity", new Object []{book});
			IOUtil.write(bookInfo(book.getId()));
			

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
				
	}

	

	

	public void printBookInfo(){
		
		IOUtil.write(PRINT_BOOK_INFO_MESSAGE);
		int id = IOUtil.readInt();
		Book book = null;
		try {
			book = (Book) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;addEntity", new Object []{book});
			while (book == null){
				IOUtil.write(BOOK_NOT_EXISTED);
				IOUtil.write(PRINT_BOOK_INFO_MESSAGE);
				id = IOUtil.readInt();
				System.out.println(bookInfo(id));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		

	}
	
	public String bookInfo(int id){
		
	
		StringBuffer str = new StringBuffer();
		Book book = null ;
		try {
			book = (Book) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getById", new Object []{id});
			str.append(book.getId());
			str.append("  ");		
			str.append(book.getTitle());
			str.append("   ");
			str.append(book.getAuthor());
			str.append("   ");
			str.append(IOUtil.DATE_FORMAT.format(book.getPublicationDate()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		return str.toString();
	}

	public void updateBook() {
	
		Book book = null;
		
		while (book == null){
			
			IOUtil.write(UPDATE_BOOK_MESSAGE);
			int id = IOUtil.readInt();
			try {
				book = (Book) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getById", new Object []{id});
			
		
			
		
		IOUtil.write(ENTER_NEW_TITLE);
		String t = IOUtil.read();
		if (!t.isEmpty()){
			book.setTitle(t);
		}
		IOUtil.write(ENTER_NEW_AUTHOR);
		if (!IOUtil.read().isEmpty()){
			book.setAuthor(IOUtil.read());
		}
		IOUtil.write(ENTER_NEW_PUBLICATION_DATE);
		if (!IOUtil.read().isEmpty()){
			book.setPublicationDate(
					IOUtil.readDate());
		}
		IOUtil.write(ENTER_NEW_PRICE);
		if (!IOUtil.read().isEmpty()){
			book.setPrice(IOUtil.readDouble());
		}
		IOUtil.write(ENTER_NEW_QUANTITY);
		if (!IOUtil.read().isEmpty()){
			book.setQuantity(IOUtil.readInt());
		}
		IOUtil.write(ENTER_NEW_RECEIPT_DATE);
		if (!IOUtil.read().isEmpty()){
			book.setReceiptDate(IOUtil.readDate());
		}
		
		
		IOUtil.write(bookInfo(book.getId()));
		
		} catch (ClassNotFoundException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
	}

	public void deleteBook() {
	
		IOUtil.write(DELETE_BOOK_MESSAGE);
		int id = IOUtil.readInt();
		Book book = null;
		try {
			book = (Book) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getById", new Object []{id});
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		while (book== null){
			IOUtil.write(BOOK_NOT_EXISTED);
			IOUtil.write(DELETE_BOOK_MESSAGE);
			id = IOUtil.readInt();
		}
		try {
			MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;removeEntityById",new Object []{ id});
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

	}

	public void saveBookListToFile(){
		
		IOUtil.write(SAVE_BOOK_LIST_TO_FILE_MESSAGE);
		String file = IOUtil.read();
		if (file.isEmpty()){
			file = FILE_TO_SAVE_DESTINATION;
			IOUtil.write(SAVED_BY_DEFAULT_IN + FILE_TO_SAVE_DESTINATION);
			
		}
		try {
			MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;saveEntityListToFile", new Object []{file});
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	
public void readBookListFromFile(){
	
	
	    
		IOUtil.write(READ_BOOK_LIST_FROM_FILE_MESSAGE);
		String file = IOUtil.read();
		if (file.isEmpty()){
			file = FILE_TO_SAVE_DESTINATION;	
			
		}
	
		
		try {
			List<Book> books = (List<Book>) MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;readEntityList",new Object []{ file});
			for(Book book:books){
				
				MessageAnalyzer.executeMethod("com.danco.training.zaneuskaya.service.impl.BookServiceImpl;addEntity", new Object []{book});
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
			
		}

	



}

